package cn.stylefeng.guns.modular.business.timer;

import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author liuyao
 * 定时任务
 */
@Component
@Slf4j
public class TimerService {


    @Value("${nohupLog.size}")
    private String size;


    @Value("${nohupLog.baseDir}")
    private String baseDir;

    private static String dir = "nohupLog/";

    /**
     * 5分钟一次，判断nohup.out文件的大小，超过10M，拿下来，然后存储到一个文件夹里，该文件夹只保存最新的10个文件
     */
    @Scheduled(fixedRate = 5 * 60 * 1000)
    public void dealNohupOut() {
        File file = new File(baseDir + dir);
        if (!file.exists()) {
            file.mkdirs();
        }
        File fileNoh = new File(baseDir + "nohup.out");
        if (!fileNoh.exists()) {
            return;
        }
        long length = fileNoh.length();
        //将配置的文件大小统一处理成Byte
        Long sizeNew = 0L;
        if (size.toLowerCase().contains("gb")) {
            sizeNew = Long.valueOf(size.toLowerCase().replace("gb", "")) * 1024 * 1024 * 1024;
        } else if (size.toLowerCase().contains("mb")) {
            sizeNew = Long.valueOf(size.toLowerCase().replace("mb", "")) * 1024 * 1024;
        } else if (size.toLowerCase().contains("kb")) {
            sizeNew = Long.valueOf(size.toLowerCase().replace("kb", "")) * 1024;
        } else {
            sizeNew = 1024 * 1024 * 10L;//默认10M
        }
        //如果日志已经超过 处理文件
        if (length >= sizeNew) {
            //判断目录下已有的文件数
            File[] files = file.listFiles();
            if (files.length > 10) {
                //删除到只保留十个
                Arrays.sort(files, new Comparator<File>() {
                    @Override
                    public int compare(File o1, File o2) {
                        return (int) (o2.lastModified() - o1.lastModified());
                    }
                });
            }
            for (int i = 0; i < files.length; i++) {
                if (i > 9) {
                    File cur = files[i];
                    cur.delete();
                }
            }
            List<String> commands = new ArrayList<>();
            commands.add("cd " + baseDir);
            commands.add("cp " + baseDir + "nohup.out" + " " + baseDir + dir + DateUtil.format(new Date(), "yyyyMMddHHmmss"));
            commands.add(">" + baseDir + "nohup.out");
            executeNewFlow(commands);
        }
    }

    //服务器执行命令行方法
    public List<String> executeNewFlow(List<String> commands) {
        List<String> rspList = new ArrayList<String>();
        Runtime run = Runtime.getRuntime();
        try {
            Process proc = run.exec("/bin/bash", null, null);
            BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
            for (String line : commands) {
                out.println(line);
            }
            out.println("exit");// 这个命令必须执行，否则in流不结束。
            String rspLine = "";
            while ((rspLine = in.readLine()) != null) {
                System.out.println(rspLine);
                rspList.add(rspLine);
            }
            proc.waitFor();
            in.close();
            out.close();
            proc.destroy();
        } catch (IOException e1) {
            e1.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return rspList;
    }


    @Value("${spring.profiles.active}")
    private String active;





    /**

     * 判断操作系统是否是Windows

     *

     * @return

     */

    public static boolean isWindowsOS() {

        boolean isWindowsOS = false;

// 注：这里的system，系统指的是 JRE (runtime)system，不是指 OS

        String osName = System.getProperty("os.name");

        if (osName.toLowerCase().indexOf("windows") > -1) {

            isWindowsOS = true;

        }

        return isWindowsOS;

    }


    /**
     * 获取Linux进程的PID
     * @param command
     * @return
     */
    public static String getPID(String command){
        BufferedReader reader =null;
        try{
            //显示所有进程
            Process process = Runtime.getRuntime().exec("ps -ef|grep java");
            reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line = null;
            while((line = reader.readLine())!=null){
                if(line.contains(command)){
                    System.out.println("相关信息 -----> "+command);
                    String[] strs = line.split("\\s+");
                    return strs[1];
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if(reader!=null){
                try {
                    reader.close();
                } catch (IOException e) {

                }
            }
        }
        return null;
    }

    /**
     * 关闭Linux进程
     * @param Pid 进程的PID
     */
    public static void closeLinuxProcess(String Pid){
        Process process = null;
        BufferedReader reader =null;
        try{
            //杀掉进程
            process = Runtime.getRuntime().exec("kill -9 "+Pid);
            reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line = null;
            while((line = reader.readLine())!=null){
                System.out.println("kill PID return info -----> "+line);
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if(process!=null){
                process.destroy();
            }

            if(reader!=null){
                try {
                    reader.close();
                } catch (IOException e) {

                }
            }
        }
    }



    /**

     * 获取Linux下的IP地址

     *

     * @return IP地址

     * @throws SocketException

     */

    private static String getLinuxLocalIp() throws SocketException {

        String ip = "";

        try {

            for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {

                NetworkInterface intf = (NetworkInterface) en.nextElement();

                String name = intf.getName();

                if (!name.contains("docker") && !name.contains("lo")) {

                    for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {

                        InetAddress inetAddress = (InetAddress) enumIpAddr.nextElement();

                        if (!inetAddress.isLoopbackAddress()) {

                            String ipaddress = inetAddress.getHostAddress().toString();

                            if (!ipaddress.contains("::") && !ipaddress.contains("0:0:")

                                    && !ipaddress.contains("fe80")) {

                                ip = ipaddress;

                            }

                        }

                    }

                }

            }

        } catch (SocketException ex) {

            ip = "127.0.0.1";

            ex.printStackTrace();

        }

        return ip;

    }

}
